package me.xplabs.engine.display 
{
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.filters.BitmapFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.ui.Mouse;
	import flash.ui.MouseCursor;
	import me.xplabs.constant.Screen;
	import me.xplabs.event.MMouseEvent;
	import me.xplabs.interfaces.IBaseDisplay;
	/**
	 * ...
	 * @author xiaohan
	 */
	
	 [Event(name = "MMouseEvent.CLICK", type = "me.xplabs.event.MMouseEvent")]
	 [Event(name = "MMouseEvent.DOUBLE_CLICK", type = "me.xplabs.event.MMouseEvent")]
	 [Event(name = "MMouseEvent.MOUSE_DOWN", type = "me.xplabs.event.MMouseEvent")]
	 [Event(name = "MMouseEvent.MOUSE_UP", type = "me.xplabs.event.MMouseEvent")]
	 [Event(name = "MMouseEvent.ROLL_OVER", type = "me.xplabs.event.MMouseEvent")]
	 [Event(name = "MMouseEvent.ROLL_OUT", type = "me.xplabs.event.MMouseEvent")]
	 [Event(name = "MMouseEvent.EVENT", type = "me.xplabs.event.MMouseEvent")]
	public class BaseDisplay extends EventDispatcher
	{
		public var x:int;
		public var y:int;
		public var width:int;
		public var height:int;
		public var name:String;
		
		public var parent:BaseDisplayContainer;
		public var data:*;
	
		public var mouseEnable:Boolean;
		
		public var mouseX:Number;
		public var mouseY:Number;
		public var stageX:Number;
		public var stageY:Number;
		
		public var isRollOver:Boolean;
		protected var isDown:Boolean;
		protected var isClick:Boolean;
		protected var hasBitmapData:Boolean;
		
		protected var _rect:Rectangle;
		protected var _point:Point;
		protected var _zeroPoint:Point;
		protected var _filterBitmapData:BitmapData;
		protected var _filter:BitmapFilter;
		protected var _filterRect:Rectangle;
		
		protected var _colorTransform:ColorTransform;
		protected var _transformBitmapData:BitmapData;
		protected var isRender:Boolean;
		public var doubleClickEnabled:Boolean;
		
		public var stage:BitmapData;
		public var buttonMode:Boolean;
		public var rotation:Number;
		protected var _matrix:Matrix;
		public function BaseDisplay() 
		{
			_rect = new Rectangle();
			_point = new Point();
			_zeroPoint = new Point();
			doubleClickEnabled = false;
			mouseEnable = true;
			isRender = true;
			rotation = 0;
		}
		public function update(container:BitmapData):void
		{
			stage = container;
			if (!data) return;
			//_point.x = x;
			//_point.y = y;
			_point.x = localX;
			_point.y = localY;
			_rect = data.rect;
			trim();
			if (!isRender) return;
			if (width != 0 || height != 0) 
			{
				_rect.width = width;
			}
			if (_filter)
			{
				_filterBitmapData = BitmapData(data).clone();
				_filterBitmapData.applyFilter(data, data.rect, _zeroPoint, _filter);
				container.copyPixels(_filterBitmapData, _rect, _point, null, null , true);
			}else if(_colorTransform) 
			{
				_transformBitmapData = BitmapData(data).clone();
				_transformBitmapData.colorTransform(data.rect, _colorTransform);
			}
			else
			{
				container.copyPixels(data, _rect, _point, null, null , true);
			}
		}
		
		public function checkBitmapData():Boolean
		{
			if (!mouseEnable || !data) return false;
			hasBitmapData = (BitmapData(data).getPixel32(mouseX - _point.x, mouseY - _point.y) > 0);
			return hasBitmapData;
		}
		public function dispatchRollEvent(isEvent:Boolean = false):BaseDisplay
		{
			if (!mouseEnable || !data) return null;
			hasBitmapData = (BitmapData(data).getPixel32(mouseX - _point.x, mouseY - _point.y) > 0);
			if (hasBitmapData && !isEvent)
			{
				if (!isRollOver)
				{
					if (hasEventListener(MMouseEvent.ROLL_OVER))
					{
						dispatchEvent(new MMouseEvent(MMouseEvent.ROLL_OVER));
						if(buttonMode) Mouse.cursor = MouseCursor.BUTTON;
					}
				}
				isRollOver = true;
				return this;
			}else
			{
				if (isRollOver)
				{
					if (hasEventListener(MMouseEvent.ROLL_OUT))
					{
						dispatchEvent(new MMouseEvent(MMouseEvent.ROLL_OUT));
						if(buttonMode) Mouse.cursor = MouseCursor.AUTO;
					}
				}
				isRollOver = false;
				isDown = false;
			}
			return null;
		}
		/**
		 * 检测是否有鼠标时间抛出
		 * @param	p_type 事件的类型
		 * @return
		 */
		public function checkMouse(p_type:String = ""):Boolean
		{
			if (!mouseEnable || !data) return false;
			if (!data) return false;
			if (hasBitmapData) 
			{
				switch(p_type)
				{
					case MMouseEvent.CLICK:
						if (isClick && hasEventListener(p_type)) dispatchEvent(new MMouseEvent(p_type));
						isClick = false;
						break;
					case MMouseEvent.DOUBLE_CLICK:
						if (!doubleClickEnabled)
						{
							if (isClick && hasEventListener(MMouseEvent.CLICK)) dispatchEvent(new MMouseEvent(MMouseEvent.CLICK));		
						}else
						{
							if (isClick && hasEventListener(p_type)) dispatchEvent(new MMouseEvent(p_type));
						}
						isClick = false;
						break;
					case MMouseEvent.MOUSE_DOWN:
						isDown = true;
						if (hasEventListener(p_type)) dispatchEvent(new MMouseEvent(p_type));
						break;
					case MMouseEvent.MOUSE_UP:
						if (hasEventListener(p_type)) dispatchEvent(new MMouseEvent(p_type));
						if (isDown) isClick = true;
						isDown = false;
						break;
				}
			}
			return hasBitmapData;
		}
		
		public function applyFilter(filter:BitmapFilter = null,render:Boolean = true):void
		{
			_filter = filter
			if (!_filter)
			{
				if (_filterBitmapData)
				{
					_filterBitmapData.dispose();
					_filterBitmapData = null;
				}
			}
		}
		public function colorTransform(colorTransform:ColorTransform = null):void
		{
			_colorTransform = colorTransform;
			if (!_colorTransform && _transformBitmapData)
			{
				_transformBitmapData.dispose();
				_transformBitmapData = null;
			}
		}
		public function get localY():int
		{
			if (!parent) return y;
			return y + parent.localY;
		}
		public function get localX():int
		{
			if (!parent) return x;
			return x + parent.localX;
		}
		/**
		 * 裁切超出屏幕的部分
		 */
		public function trim():void
		{
			if (localX < 0)
			{
				_rect.x = - localX;
				_rect.width = data.width + localX;
				//_rect.x = 0 - localX;
				//_rect.width = data.width -(0 - localX);
			}else
			{
				_rect.x = 0;
				_rect.width = data.width;
				if (localX + data.width > Screen.stageW) _rect.width = Screen.stageW - localX;
			}
			if (localY < 0)
			{
				_rect.y = -localY;
				_rect.height = data.height + localY;
				//_rect.y = 0 - localY;
				//_rect.height = data.height -(0 - localY);
			}else
			{
				_rect.y = 0;
				_rect.height = data.height;
				if (localY + data.height > Screen.stageH) _rect.height = Screen.stageH - localY;
			}
			isRender = !_rect.isEmpty();
		}
		public function checkRollEvent(isEvent:Boolean = false):void
		{
		}
		public function checkMouseEvent(p_type:String = ""):Boolean
		{
			return false;
		}
		public function dispose():void
		{
			if (data)
			{
				data = null;
			}
			applyFilter();
			colorTransform();
			isClick = false;
			isDown = false;
			doubleClickEnabled = false;
			mouseEnable = true;
			_rect.setEmpty();
			_zeroPoint.x = 0;
			_zeroPoint.y = 0;
		}
		
	}
}